<?php

use \GatewayWorker\Lib\Gateway;
use App\Models\KfDialog;
use App\Models\KfMessage;

// 会话处理

class Dialog
{
    public static function handle($payload)
    {
        if (isset($payload['memory'])) {
            print_r(Cache::getMemoryUsage(1));
            return;
        }

        /* 会话处理流程
         * 1.判断会话是否存在，不存在创建新会话
         * 2.会话已存在，判断会话是否被禁用，已禁用并且在禁用期，不处理
         * 3.会话未禁用，判断会话内容是否存在敏感词，有则禁用会话
         */

        $hasBadWord = Message::disableWordExists($payload['content']);
        $isUserBanned = Cache::isUserBanned($payload['user_id']);

        $hasDialog = Cache::hasDialog($payload['user_id']);

        if($hasDialog)
        {
            Cache::updateDialog($payload);
            $dialog = Cache::getDialogByUserId($payload['user_id']);

        } else {
            // 更新消息表 更新未读消息记录 更新过期时间
            $payload['status'] = ($hasBadWord || $isUserBanned) ? 'banned' : 'pending';
            $dialog = static::create($payload);
        }

        if ($isUserBanned) {
            // 用户处于禁言 保存消息并设置为禁言状态
            Message::save($dialog['dialog_id'], $payload['content'], 'banned');
            self::autoReply($dialog);
        } else {
            // 保存消息到数据库
            Message::save($dialog['dialog_id'], $payload['content']);
        }

        if ($hasBadWord) {
            // print_r('存在敏感词, 开始关小黑屋...');
            // 存在敏感词 把会话移入禁用列表 更新会话为禁用状态 同时更新数据库状态
            Cache::disable($dialog);
            
            KfDialog::where('id', $dialog['dialog_id'])->update(
                [
                    'status' => 'banned',
                    'banned_at' => date('Y-m-d H:i:s', strtotime('+1 days'))
                ]
            );

            self::autoReply($dialog);
        }

        // 新消息推送给所有客服
        if ($dialog['status'] == 'pending') {
            $data = Cache::getWaitingDialogs();
            $servers = Cache::getOnlineServer();
            
            foreach ($servers as $server) {
                Gateway::sendToUid($server['server_id'], json_encode(['type' => 'waiting', 'data' => $data]));
            }
        }
        if ($dialog['status'] == 'joined') {
            $client = Gateway::getClientIdByUid($dialog['server_id']);
            $server = Cache::getServer($dialog['server_id']);
            if ($server['last_user_id'] == $dialog['user_id']) {
                $joined_info = Cache::getDialogAndResetUnread($dialog['user_id']);
                Gateway::sendToClient($client[0], json_encode(['type' => 'joined_info', 'message' => 'ok', 'code' => 200, 'data' => $joined_info]));
            } else {
                $joined = Cache::getJoined($dialog['server_id']);
                Gateway::sendToClient($client[0], json_encode(['type' => 'joined', 'message' => 'ok', 'code' => 200, 'data' => $joined]));
            }
        }
    }

    protected static function autoReply($dialog)
    {

        $autoReplyMsg = '尊敬的用户您好，由于您发送的信息存在敏感词语，今日无法接入人工服务，请明天再试，谢谢。';

        $kf_message = [
            'dialog_id' => $dialog['dialog_id'],
            'role' => 'server',
            'content' => $autoReplyMsg,
            'is_auto' => 1,
        ];

        KfMessage::create($kf_message);

        $message = ['user_id' => $dialog['user_id'], 'content' => $autoReplyMsg, 'is_auto' => 1];

        Cache::setServerMessage($dialog['user_id'], $message);

        Message::sendToUser(config('MESSAGE_API_URL'), [
            'user_id' => $dialog['user_id'],
            'message' => $autoReplyMsg,
        ]);
    }

    protected static function create($payload)
    {
        $dialog = KfDialog::create([
            'appid'     =>  $payload['appid'],
            'user_id'   =>  $payload['user_id'],
            'admin_id'  =>  $payload['admin_id'],
            'channel'   =>  $payload['channel'],
            'nickname'  =>  $payload['nickname'],
            'avatar'    =>  $payload['avatar'],
            'status'    =>  $payload['status'],
        ]);

        $payload['dialog_id'] = $dialog->id;

        return Cache::create($payload);
    }

    protected static function updateStatus($dialog_id)
    {
        $db = DB::instance();
        $db->update('yy_kf_dialog')->cols(array('status' => 'banned', 'banned_at' => date('Y-m-d H:i:s', strtotime('+1 days'))))->where('id=' . $dialog_id)->query();
    }

    public static function addOpenedForOne($user_id, $server_id)
    {
        $dialog = Cache::getDialogByUserId($user_id);
        if (Cache::setAddOpened($user_id, $server_id)) {
            KfDialog::where('id', $dialog['dialog_id'])->update(['server_id' => $server_id]);
        }
        return 1;
    }

    public static function addOpenedForWechat($wechat_id, $server_id)
    {
        if ($dialogIds = Cache::setAddOpenedForWechat($wechat_id, $server_id)) {
            KfDialog::whereIn('id', $dialogIds)->update(['server_id' => $server_id]);
        }
        return 1;
    }

    public static function close($payload)
    {
        if (Cache::checkExpire($payload['user_id'])) {
            KfDialog::where('id', $payload['dialog_id'])->update(['status' => 'finished']);
        }
    }
}
